package client;

import java.util.*;
import common.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

public class BasicGUI extends Observable implements Observer {
	final static int SERVER_PORT = 49302;
	static InetAddress SERVER_IP;
	
	private AtomicInteger ai = new AtomicInteger(0);
	private ClientGameState gs;
	
	public static void main (String [] arg) throws InterruptedException {
		try {SERVER_IP = InetAddress.getLocalHost();} catch (Exception e){ e.printStackTrace(); }
		BasicGUI bg = new BasicGUI();
		
//		Server server = new Server( SERVER_PORT );
//		server.start();
		
		Thread.sleep(1000);
		
		NetworkClient nc = new NetworkClient( SERVER_IP, SERVER_PORT );
		final ClientGameState cgs = new ClientGameState();
		nc.addObserver(cgs);
		cgs.addObserver(bg);
		bg.addObserver(nc);
		nc.start();	
		
		while (!nc.started()) {
			if (nc.failed()) throw new RuntimeException(nc.failure());
			try { Thread.sleep(500); } catch (Exception e){}
			System.out.println("Waiting for Socket...");
		}
		new Thread(new Runnable(){public void run(){cgs.listen();}}).start();
		
		bg.primitiveGUI(cgs);
		if (nc.failed()) nc.failure().printStackTrace();
		
//		server.suggestShutdown();
	}
	
	public void primitiveGUI(ClientGameState cgs) {
		gs = cgs;
		String in = "";
		Scanner sc = new Scanner(System.in);
		//Player p = new Player("Me");
		
		while (!in.equalsIgnoreCase("Q")) {
			System.out.println("Commands : HLP,Q\n");
			in = sc.nextLine();
			
			try {
					
				if (in.equalsIgnoreCase("HLP")) {
					System.out.println("Commands :");
					System.out.println("Register Name Round#");
					System.out.println("RoundRequest");
					System.out.println("Ask RICE 1.0 20 100");
					System.out.println("Bid WATER 1.0 20 100");
				} else if (in.startsWith("Register")) {
					this.setChanged();
					String [] b = in.split(" ");
					this.notifyObservers(new Register(b[1], gs.findRound(Integer.parseInt(b[2]))));
				} else if (in.startsWith("RoundRequest")) {
					this.setChanged();
					this.notifyObservers(new RoundRequest());
				} else if (in.startsWith("Ask")) {
					String [] b = in.split("\\s+");
					Commodity e1 = Commodity.valueOf(b[1]);
					Ask a = new Ask (cgs.getPlayer().getName(),e1, Double.parseDouble(b[2]), Integer.parseInt(b[3]),Long.parseLong(b[4]), TimeUnit.MILLISECONDS );
					this.setChanged();
					this.notifyObservers(a);
				} else if (in.startsWith("Bid")) {
					String [] b = in.split("\\s+");
					Commodity e1 = Commodity.valueOf(b[1]);
					Bid a = new Bid (cgs.getPlayer().getName(),e1, Double.parseDouble(b[2]), Integer.parseInt(b[3]),Long.parseLong(b[4]), TimeUnit.MILLISECONDS );
					this.setChanged();
					this.notifyObservers(a);
				}
			
			} catch( Exception e ) {
				System.out.println("Unacceptable input. Cry.");
			}
			
			
			if (ai.get() > 0) processQ();
		}
		System.err.println("Gui is Dead");

	}
	
	private void processQ() {
		System.err.println("GUI Says : Gamestate Updated!");
		System.err.println("GUI Says : \n" + gs.toString());
		ai.decrementAndGet();
//		Sendable s = Q.remove();
//		gs.
//		if (s.getType().equals("RoundList")) {
//			RoundList s2 = (RoundList)s;
//			if( s2.size() > 0 )
//				r = s2.remove(0);
//			
//			System.out.println("Received a roundlist of " + s2.size() + " rounds.");
//		}
//		System.err.println("GUI Says : I just recieved a sendable! : " + s);
	}
	
	//Called by client gamestate thread.
	public void update(Observable arg0, Object arg1) {
		ai.incrementAndGet();
	}

}
